package assist.domain.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;


/**
 * A container for shots, which also sorts into subcontainers of Missed, Ongoal,
 * Blocks, Goals, at goal.
 * 
 * NOTE:
 * Problem with the Shot hierarchy, with GAE/JDO:
 *  1. A List of a type of class cannot contain objects of a subclass type.
 *    * A persistent List<ShotOnGoal> cannot contain an object of type Goal.
 *    * This is supposed to be fixed in future release.
 *      * Will require the superclass_table inheritance strategy to be supported. 
 *    * This IS possible in Objectify, but only as Qury, nnot list, so still requires
 *      a DAO.    
 *  2. Cannot have 2 fields in the class that are both lists of a type with a 
 *     common base class both persisted.
 *     * Can't have List<Goal> and List<ShotOnGoal>
 *     * Not sure if Objectify fixes this.
 *     
 *  NOTE: To address above problems, we created a DAO layer that must manage
 *  the persistence where it has the above problems.
 *  
 *  NOTE: With DAO/JDO Solution, must be wary of concrete classes that are 
 *  inherited from other concrete classes.  Must decide how it will work,
 *        * Goals can still derive from Shot BUT:
 *           * Will need to be persisted separately. 
 *           * A shot AND a Goal both need to be created by parser.
 *        * NOTE: Will have same problem(s) with BlockedShots
 *        * NOTE: Also penalties, Faceoffs. *  
 */
public class Shots  implements Serializable
{       
    private static final long serialVersionUID = 1L;
    private List<Shot> shots = new ArrayList<Shot>();      
    private List<BlockedShot> blocked = new ArrayList<BlockedShot>();        
    private List<ShotOnGoal> onGoal = new ArrayList<ShotOnGoal>();       
    private List<MissedShot> missed = new ArrayList<MissedShot>();    
    private List<Goal> goals = new ArrayList<Goal>();       
    private List<Shot> atGoal = new ArrayList<Shot>();

    
    public void addShot(final Shot shot)
    {
        this.shots.add(shot);
        this.sortShot(shot);
    }
    
    private void sortShot(final Shot shot)
    {
       //TODO: Need to figure out if We are also adding Shots as ShotOnGoal or not.
        if (shot instanceof ShotOnGoal)
        {
            this.onGoal.add((ShotOnGoal)shot);
        }
        //TODO: Need to figure out if We are also adding Shots as ShotOnGoal or not.
        if (shot instanceof Goal)
        {
            this.goals.add((Goal)shot);
        }  
        
        if (shot instanceof MissedShot)
        {
            this.missed.add((MissedShot)shot);
        }
        if (shot instanceof ShotOnGoal || shot instanceof MissedShot)
        {
            this.atGoal.add(shot);
        }
        if (shot instanceof BlockedShot)
        {
            this.blocked.add((BlockedShot)shot);
        }
      
    }
    
    /**
     * All Shots, AKA Corsi.
     * @return
     */
    public List<Shot> getAll()
    {
        return this.shots;
    }

    public List<ShotOnGoal> getOnGoal()
    {        
        return this.onGoal;
    }

    /**
     * Excludes Blocked shots.  AKA Fenwick.  On Goal + Missed.
     * @return
     */
    public List<Shot> getAtGoal()
    {     
        return this.atGoal;
    }

    public List<BlockedShot> getBlocked()
    {        
        return this.blocked;
    }

    public List<Goal> getGoals()
    {       
        return this.goals;
    }

    public List<MissedShot> getMissed()
    {       
        return this.missed;
    }
    

    public void addAll(Collection<Shot> shots)
    {
        for (Shot shot : shots)
        {
            this.addShot(shot);
        }
    }    

    public void clearAll()
    {
        this.missed.clear();
        this.goals.clear();
        this.blocked.clear();
        this.atGoal.clear();
        this.onGoal.clear();
        this.shots.clear();        
    }
}
